﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

namespace Battle
{
    public static class CameraAnimationName
    {
        public static readonly string NONE = @"";
        
        /*
        public static readonly string ENTER_SCENE      = @"EnterSceneAni";
        public static readonly string SWITCH_CAMP      = @"SwitchCampAni";

        public static readonly string OUR_TEAM_BEHIT   = @"OurTeamBehitAni";
        public static readonly string OUR_TEAM_BEHITING= @"OurTeamBehitingAni";

        public static readonly string ULTMATE_SKILL_P1 = @"UltimateSkillAni_P1";
        public static readonly string ULTMATE_SKILL_P2 = @"UltimateSkillAni_P2";
        public static readonly string ULTMATE_SKILL_P3 = @"UltimateSkillAni_P3";
        public static readonly string ULTMATE_SKILL_P4 = @"UltimateSkillAni_P4";
        


        public static readonly string OUR_WIN = @"WinAni";
        public static readonly string ENEMY_WIN = @"DefeadAni";

        public static readonly string SHAKE = @"ShakeAniAdd";
        public static readonly string SHAKE_WEAK = @"ShakeAniAddWeak";


        public static readonly string NEAR_TO_CENTER   = @"NearToBattleCenterAni";
        public static readonly string FAR_TO_CENTER    = @"FarToBattleCenterAni";
        public static readonly string CENTER_TO_READY  = @"BattleCenterToReadyAni";
        public static readonly string CENTER_TO_NEAR   = @"BattleCenterToNearAni";
        public static readonly string CENTER_TO_FAR    = @"BattleCenterToFarAni";
        public static readonly string READY_TO_CENTER  = @"ReadyToBattleCenterAni";
        public static readonly string NEAR_TO_BATTLING = @"NearToBattlingAni";
        public static readonly string FAR_TO_BATTLING  = @"FarToBattlingAni";
        public static readonly string READY_TO_NEAR_BATTLING = @"ReadyToNearBattlingAni";
        public static readonly string READY_TO_FAR_BATTLING  = @"ReadyToFarBattlingAni";
        public static readonly string ULTIMATE_TO_CENTER = @"UlitmateToBattleCenterAni";
        public static readonly string ULTIMATE_TO_READY  = @"UltimateSkillEndAni";
        public static readonly string NEAR_TO_FAR_BATTLING = @"NearToFarBattlingAni";
        public static readonly string FAR_TO_NEAR_BATTLING = @"FarToNearBattlingAni";
        */

        public static readonly string DEFEAD = @"DefeadAni";
        public static readonly string WIN    = @"WinAni";
        public static readonly string SWITCH_CAMP = @"SwitchCampAni";

        public static readonly string SHAKE  = @"ShakeAniAdd";
        public static readonly string SHAKE_WEAK = @"ShakeAniAddWeak";

        public static readonly string ULTIMATE_SKILL_P1 = @"UltimateSkillAni_P1";
        public static readonly string ULTIMATE_SKILL_P2 = @"UltimateSkillAni_P2";
        public static readonly string ULTIMATE_SKILL_P3 = @"UltimateSkillAni_P3";
        public static readonly string ULTIMATE_SKILL_P4 = @"UltimateSkillAni_P4";

        public static readonly string ULTIMATE_SKILL_END = @"UltimateSkillEndAni";

        /// <summary>
        /// PVP
        /// </summary>
        public static readonly string PVP_ENTER_SCENE = @"PVPEnterSceneAni";
        public static readonly string PVP_RUSH_NEAR = @"PVPNearBattleAni";
        public static readonly string PVP_RUSH_FAR  = @"PVPFarBattleAni";
        public static readonly string PVP_NEAR_BATTLING = @"PVPNearBattlingAni";
        public static readonly string PVP_FAR_BATTLING  = @"PVPFarBattlingAni";
        public static readonly string PVP_OUR_TEAM_BEHIT = @"PVPOurTeamBehitAni";
        public static readonly string PVP_OUR_TEAM_BEHITING = @"PVPOurTeamBehitingAni";

        public static readonly string PVP_RUSH_NEAR_R = @"PVPNearBattleAni_R";
        public static readonly string PVP_NEAR_BATTLING_R = @"PVPNearBattlingAni_R";

        public static readonly string PVP_RUSH_NEAR_L = @"PVPNearBattleAni_L";
        public static readonly string PVP_NEAR_BATTLING_L = @"PVPNearBattlingAni_L";

    }

    public enum CameraPosition
    {
        None, 
        Ready, //准备位置
        Far,   //远方攻击位子
        Near,  //近战攻击位子
        Our,   //我放被攻击
    }

    public enum CameraAnimationType
    {
        

        /*
        ENTER_SCENE,                    // 入场

        SWITCH_CAMP,                    // 换阵

        OUR_TEAM_BEHIT,                 // Defender开始攻击
        OUR_TEAM_BEHITING,              // Defender攻击摇镜

        ULTMATE_SKILL_P1,               
        ULTMATE_SKILL_P2,
        ULTMATE_SKILL_P3,
        ULTMATE_SKILL_P4,               // Attacker 大招开始

        OUR_WIN,                        // Attacker 队伍胜利
        ENEMY_WIN,                      // Defender 胜利

        SHAKE,                          // 强震屏
        SHAKE_WEAK,                     // 弱震屏

        //状态切换
        NEAR_TO_CENTER,                 // 近战->中间
        FAR_TO_CENTER,                  // 远程->中间

        CENTER_TO_NEAR,                 // 中间->近战
        CENTER_TO_FAR,                  // 中间->远程

        CENTER_TO_READY,                // 中间->默认
        READY_TO_CENTER,                // 默认->中间

        NEAR_TO_BATTLING,               // 近战摇镜
        FAR_TO_BATTLING,                // 远程摇镜

        READY_TO_NEAR_BATTLING,         // 默认->近战
        READY_TO_FAR_BATTLING,          // 默认->远程

        ULTIMATE_TO_CENTER,             //大招->中间
        ULTIMATE_TO_READY,              //大招->默认

        NEAR_TO_FAR_BATTLING,           //近战->远程
        FAR_TO_NEAR_BATTLING,           //远程->近战
         */
        /// <summary>
        /// Common animation
        /// </summary>
        NONE,

        DEFEAD,                   //失败
        WIN,                      //胜利
        SWITCH_CAMP,              //换阵

        SHAKE,                    //强整
        SHAKE_WEAK,               //弱整

        ULTIMATE_SKILL_P1,     
        ULTIMATE_SKILL_P2,
        ULTIMATE_SKILL_P3,
        ULTIMATE_SKILL_P4,
        ULTIMATE_SKILL_END,       //大招开始1，2，3，4，END

        PVP_ENTER_SCENE,          //入场
        PVP_RUSH_NEAR,            //近战冲
        PVP_RUSH_FAR,             //远战冲
        PVP_NEAR_BATTLING,        //近站摇镜
        PVP_FAR_BATTLING,         //远战摇精
        PVP_OUR_TEAM_BEHIT,       //被打
        PVP_OUR_TEAM_BEHITING,    //被打ING


        PVP_RUSH_NEAR_R,          //近战向右冲
        PVP_NEAR_BATTLING_R,

        PVP_RUSH_NEAR_L,          //近战向左冲
        PVP_NEAR_BATTLING_L,
    }

    public enum CameraState
    {
        Free,
        Control,
        ReleaseControl,
    }

    public class CameraAnimationKit :MonoBehaviour
    {
        void Awake()
        {
            if( gameObject.GetComponent<AudioListener>()!=null )
            {
                gameObject.GetComponent<AudioListener>().enabled=false;
            }
        }

        public void Init()
        {
            this.speed=1f;
            this.startTouchPosition=Vector3.zero;
            this.currTouchPosition = Vector3.zero;
            this.changedTouchPosition = Vector3.zero;
            this.endTouchPosition=Vector3.zero;

            this.cameraViewCenter = Vector3.zero;

            this.viewCenter = Vector3.zero;
            this.enemyViewCenter = new Vector3( 0, 0, 4 );
            this.friendViewCenter= new Vector3( 0, 0, -4 );
        }

        


        /// <summary>
        /// 播放速度
        /// </summary>
        public float speed = 1f;

        //主视角摄像机
        public UnityEngine.Camera mainCamera;
        public Animation ani;

        public AnimationClip animationClip;
        public CameraPosition cameraPosition = CameraPosition.None;

        public FocusCamera focusCamera;
        public GameObject blackPlane;

        /// <summary>
        /// 添加摄像机动画
        /// </summary>
        /// <param name="ac"></param>
        /// <param name="aniName"></param>
        public void AddCameraAni( AnimationClip ac, string aniName )
        {
            if( this.ani.GetClip( aniName )!=null )
            {
                ac.wrapMode = WrapMode.ClampForever;
                this.ani.AddClip( ac, aniName );
            }
        }

        /// <summary>
        /// 移除摄像机动画
        /// </summary>
        /// <param name="aniName"></param>
        public void RemoveCameraAni( string aniName )
        {
            if( this.ani.GetClip( aniName )!=null )
            {
                this.ani.RemoveClip( aniName );
            }
        }

        /// <summary>
        /// 用于加速操作
        /// </summary>
        /// <param name="speed"></param>
        public void SetSpeed( float speed )
        {
            this.speed = speed;
        }

        /// <summary>
        /// 当前type
        /// </summary>
        public string currAni=CameraAnimationName.PVP_ENTER_SCENE;
        public CameraAnimationType cameraAnimationType = CameraAnimationType.NONE;
        public CameraState cameraState = CameraState.Free;

        public bool isRevert=false;


        public void PlayDelay( CameraAnimationType at, float duartion, bool revert = false )
        {
            StopCoroutine( "_PlayDelay" );
            StartCoroutine( _PlayDelay( at, duartion, revert ) );
        }

        IEnumerator _PlayDelay( CameraAnimationType at, float duration, bool revert = false )
        {
            yield return new WaitForSeconds( duration );
            Play( at, revert );
        }


        //bool isPlaying = false;
        //float deltaTime = 0f;
        

        public void Play( CameraAnimationType at,bool revert = false,bool isCrossFade=true,float speed = 1f)
        {
            this.cameraAnimationType = at;

            switch( at )
            {
                case CameraAnimationType.NONE:
                    break;
                case CameraAnimationType.WIN:
                    Play( CameraAnimationName.WIN, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.DEFEAD:
                    Play( CameraAnimationName.DEFEAD, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_ENTER_SCENE:
                    Play( CameraAnimationName.PVP_ENTER_SCENE, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_FAR_BATTLING:
                    Play( CameraAnimationName.PVP_FAR_BATTLING, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_NEAR_BATTLING:
                    Play( CameraAnimationName.PVP_NEAR_BATTLING, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_OUR_TEAM_BEHIT:
                    Play( CameraAnimationName.PVP_OUR_TEAM_BEHIT, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_OUR_TEAM_BEHITING:
                    Play( CameraAnimationName.PVP_OUR_TEAM_BEHITING, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_RUSH_FAR:
                    Play( CameraAnimationName.PVP_RUSH_FAR, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_RUSH_NEAR:
                    Play( CameraAnimationName.PVP_RUSH_NEAR, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.SWITCH_CAMP:
                    Play( CameraAnimationName.SWITCH_CAMP, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.ULTIMATE_SKILL_END:
                    Play( CameraAnimationName.ULTIMATE_SKILL_END, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.ULTIMATE_SKILL_P1:
                    Play( CameraAnimationName.ULTIMATE_SKILL_P1, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.ULTIMATE_SKILL_P2:
                    Play( CameraAnimationName.ULTIMATE_SKILL_P2, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.ULTIMATE_SKILL_P3:
                    Play( CameraAnimationName.ULTIMATE_SKILL_P3, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.ULTIMATE_SKILL_P4:
                    Play( CameraAnimationName.ULTIMATE_SKILL_P4, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_RUSH_NEAR_R:
                    Play( CameraAnimationName.PVP_RUSH_NEAR_R, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_RUSH_NEAR_L:
                    Play( CameraAnimationName.PVP_RUSH_NEAR_L, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_NEAR_BATTLING_R:
                    Play( CameraAnimationName.PVP_NEAR_BATTLING_R, revert, isCrossFade, speed );
                    break;
                case CameraAnimationType.PVP_NEAR_BATTLING_L:
                    Play( CameraAnimationName.PVP_NEAR_BATTLING_L, revert, isCrossFade, speed );
                    break;
            }
        }

        void Play( string aniName, bool revert, bool isCrossFade=true,float speed = 1f )
        {
            this.ani.enabled=true;
            this.currAni = aniName;

            this.speed = speed;
            this.isRevert = revert;
            this.cameraState = CameraState.Free;

            this.animationClip = ani.GetClip( aniName );


            if( this.animationClip!=null )
            {
                int val = revert?-1:+1;

                this.ani[aniName].speed= val * this.speed;
                this.ani[aniName].normalizedTime = revert?1:0;
                if( isCrossFade )
                    this.ani.CrossFade( aniName );
                else
                    this.ani.Play( aniName );
            }
            else
            {
                Debug.LogErrorFormat( "not has this animation %s", aniName );
            }

            //Debug.Log( "[DEBUG] Played Animation:<color=red>"+aniName+"</color>" );

            StopCoroutine( "CalcCameraPosition" );
            StartCoroutine( CalcCameraPosition() );
        }

        IEnumerator CalcCameraPosition()
        {
            cameraPosition = CameraPosition.None;

            var dt = GetAniLength( cameraAnimationType );
            yield return new WaitForSeconds( dt );

            if(cameraAnimationType == CameraAnimationType.PVP_ENTER_SCENE && isRevert == false)
            {
                cameraPosition = CameraPosition.Ready;
            }

            else if( cameraAnimationType == CameraAnimationType.PVP_RUSH_FAR )
            {
                if( !isRevert )
                {
                    cameraPosition = CameraPosition.Far;
                }
                else
                {
                    cameraPosition = CameraPosition.Ready;
                }
            }

            else if(cameraAnimationType == CameraAnimationType.PVP_RUSH_NEAR)
            {
                if(!isRevert)
                {
                    cameraPosition = CameraPosition.Near;
                }
                else
                {
                    cameraPosition = CameraPosition.Ready;
                }
            }

            else if(cameraAnimationType == CameraAnimationType.PVP_OUR_TEAM_BEHIT)
            {
                if(!isRevert)
                {
                    cameraPosition = CameraPosition.Our;
                }
                else
                {
                    cameraPosition = CameraPosition.Ready;
                }
            }
        }

        /// <summary>
        /// 震动接口
        /// </summary>
        public void Shake( int id=0 )
        {
            shakeState = id;
            shakeTimer = 0;
            //Debug.Log("camera shake: " + id);
            //if( id==0 ) id = 1;

            //if( ani.IsPlaying( CameraAnimationName.SHAKE_WEAK ) ) ani.Stop( CameraAnimationName.SHAKE_WEAK );
            //if( ani.IsPlaying( CameraAnimationName.SHAKE ) ) ani.Stop( CameraAnimationName.SHAKE );

            //if( id==1 )
            //{

            //    if( ani.GetClip( CameraAnimationName.SHAKE_WEAK )!=null )
            //    {
            //        ani[CameraAnimationName.SHAKE_WEAK].blendMode = AnimationBlendMode.Additive;
            //        ani[CameraAnimationName.SHAKE_WEAK].enabled = true;
            //        ani[CameraAnimationName.SHAKE_WEAK].weight=1;
            //        ani[CameraAnimationName.SHAKE_WEAK].wrapMode = WrapMode.ClampForever;

            //        ani[CameraAnimationName.SHAKE_WEAK].normalizedTime=0f;
            //        ani.Blend( CameraAnimationName.SHAKE_WEAK, 0f );
            //    }
            //    else
            //    {
            //        Debug.LogErrorFormat( "not has this animation ShakeAniAdd!!" );
            //    }
            //}

            //else if( id==2 )
            //{
            //    if( ani.GetClip( CameraAnimationName.SHAKE )!=null )
            //    {
            //        ani[CameraAnimationName.SHAKE].blendMode = AnimationBlendMode.Additive;
            //        ani[CameraAnimationName.SHAKE].enabled = true;
            //        ani[CameraAnimationName.SHAKE].weight=1;
            //        ani[CameraAnimationName.SHAKE].wrapMode = WrapMode.ClampForever;

            //        ani[CameraAnimationName.SHAKE].normalizedTime=0f;
            //        ani.Blend( CameraAnimationName.SHAKE, 0f );
            //    }
            //    else
            //    {
            //        Debug.LogErrorFormat( "not has this animation ShakeAniAdd!!" );
            //    }
            //}
        }


        public float GetAniLength( CameraAnimationType at )
        {
            switch( at )
            {
                 /*
                case CameraAnimationType.ENTER_SCENE:
                    return ani.GetClip( CameraAnimationName.ENTER_SCENE ).length;
                case CameraAnimationType.SWITCH_CAMP:
                    return ani.GetClip( CameraAnimationName.SWITCH_CAMP ).length;
           
                case CameraAnimationType.OUR_WIN:
                    return ani.GetClip( CameraAnimationName.OUR_WIN ).length;
                case CameraAnimationType.ENEMY_WIN:
                    return ani.GetClip( CameraAnimationName.ENEMY_WIN ).length;

                case CameraAnimationType.OUR_TEAM_BEHIT:
                    return ani.GetClip( CameraAnimationName.OUR_TEAM_BEHIT ).length;
                case CameraAnimationType.OUR_TEAM_BEHITING:
                    return ani.GetClip( CameraAnimationName.OUR_TEAM_BEHITING ).length;

                case CameraAnimationType.CENTER_TO_READY:
                    return ani.GetClip( CameraAnimationName.CENTER_TO_READY ).length;
                case CameraAnimationType.READY_TO_CENTER:
                    return ani.GetClip( CameraAnimationName.READY_TO_CENTER ).length;
                case CameraAnimationType.CENTER_TO_FAR:
                    return ani.GetClip( CameraAnimationName.CENTER_TO_FAR ).length;
                case CameraAnimationType.CENTER_TO_NEAR:
                    return ani.GetClip( CameraAnimationName.CENTER_TO_NEAR ).length;
                case CameraAnimationType.NEAR_TO_BATTLING:
                    return ani.GetClip( CameraAnimationName.NEAR_TO_BATTLING ).length;
                case CameraAnimationType.FAR_TO_BATTLING:
                    return ani.GetClip( CameraAnimationName.FAR_TO_BATTLING ).length;
                case CameraAnimationType.FAR_TO_CENTER:
                    return ani.GetClip( CameraAnimationName.FAR_TO_CENTER ).length;
                case CameraAnimationType.NEAR_TO_CENTER:
                    return ani.GetClip( CameraAnimationName.NEAR_TO_CENTER ).length;
                case CameraAnimationType.READY_TO_NEAR_BATTLING:
                    return ani.GetClip( CameraAnimationName.READY_TO_NEAR_BATTLING ).length;
                case CameraAnimationType.READY_TO_FAR_BATTLING:
                    return ani.GetClip( CameraAnimationName.READY_TO_FAR_BATTLING ).length;
                case CameraAnimationType.ULTIMATE_TO_CENTER:
                    return ani.GetClip( CameraAnimationName.ULTIMATE_TO_CENTER ).length;

                case CameraAnimationType.ULTMATE_SKILL_P1:
                    return ani.GetClip(CameraAnimationName.ULTMATE_SKILL_P1).length;
                case CameraAnimationType.ULTMATE_SKILL_P2:
                    return ani.GetClip( CameraAnimationName.ULTMATE_SKILL_P2 ).length;
                case CameraAnimationType.ULTMATE_SKILL_P3:
                    return ani.GetClip( CameraAnimationName.ULTMATE_SKILL_P3 ).length;
                case CameraAnimationType.ULTMATE_SKILL_P4:
                    return ani.GetClip( CameraAnimationName.ULTMATE_SKILL_P4 ).length;
                case CameraAnimationType.ULTIMATE_TO_READY:
                    return ani.GetClip( CameraAnimationName.ULTIMATE_TO_READY ).length;
                  * */

                case CameraAnimationType.WIN:
                    return ani.GetClip( CameraAnimationName.WIN ).length;
                case CameraAnimationType.DEFEAD:
                    return ani.GetClip( CameraAnimationName.DEFEAD ).length;
                case CameraAnimationType.PVP_ENTER_SCENE:
                    return ani.GetClip( CameraAnimationName.PVP_ENTER_SCENE ).length;
                case CameraAnimationType.PVP_FAR_BATTLING:
                    return ani.GetClip( CameraAnimationName.PVP_FAR_BATTLING ).length;
                case CameraAnimationType.PVP_NEAR_BATTLING:
                    return ani.GetClip( CameraAnimationName.PVP_NEAR_BATTLING ).length;
                case CameraAnimationType.PVP_NEAR_BATTLING_R:
                    return ani.GetClip( CameraAnimationName.PVP_NEAR_BATTLING_R ).length;
               
                case CameraAnimationType.PVP_NEAR_BATTLING_L:
                    return ani.GetClip( CameraAnimationName.PVP_NEAR_BATTLING_L ).length;
                case CameraAnimationType.PVP_OUR_TEAM_BEHIT:
                    return ani.GetClip( CameraAnimationName.PVP_OUR_TEAM_BEHIT ).length;
                case CameraAnimationType.PVP_OUR_TEAM_BEHITING:
                    return ani.GetClip( CameraAnimationName.PVP_OUR_TEAM_BEHITING ).length;
                case CameraAnimationType.PVP_RUSH_FAR:
                    return ani.GetClip( CameraAnimationName.PVP_RUSH_FAR ).length;
                case CameraAnimationType.PVP_RUSH_NEAR:
                    return ani.GetClip( CameraAnimationName.PVP_RUSH_NEAR ).length;
                case CameraAnimationType.PVP_RUSH_NEAR_R:
                    return ani.GetClip( CameraAnimationName.PVP_RUSH_NEAR_R ).length;
                case CameraAnimationType.PVP_RUSH_NEAR_L:
                    return ani.GetClip( CameraAnimationName.PVP_RUSH_NEAR_L ).length;
                case CameraAnimationType.SWITCH_CAMP:
                    return ani.GetClip( CameraAnimationName.SWITCH_CAMP ).length;
                case CameraAnimationType.ULTIMATE_SKILL_END:
                    return ani.GetClip( CameraAnimationName.ULTIMATE_SKILL_END ).length;
                case CameraAnimationType.ULTIMATE_SKILL_P1:
                    return ani.GetClip( CameraAnimationName.ULTIMATE_SKILL_P1 ).length;
                case CameraAnimationType.ULTIMATE_SKILL_P2:
                    return ani.GetClip( CameraAnimationName.ULTIMATE_SKILL_P2 ).length;
                case CameraAnimationType.ULTIMATE_SKILL_P3:
                    return ani.GetClip( CameraAnimationName.ULTIMATE_SKILL_P3 ).length;
                case CameraAnimationType.ULTIMATE_SKILL_P4:
                    return ani.GetClip( CameraAnimationName.ULTIMATE_SKILL_P4 ).length;
            }

            throw new Exception( "not has this animtaion:"+at );
        }

        /// <summary>
        /// 慢镜头效果
        /// </summary>
        /// <param name="speed"></param>
        /// <param name="delay"></param>
        public void SlowMotionEffect( float speed, float delay )
        {
            if( delay <= 0 ) return;
            if( speed <0 ) speed = 0;

            Time.timeScale = speed;
            Invoke( "BackCameraSpeed", delay );
        }

        void BackCameraSpeed()
        {
            Time.timeScale=1.0f;
        }

        #region 相机控制逻辑
        public bool canHoldOnScreen=true;

        public bool onTouchScreen=false;

        public float startTouchTime=0f;
        public float endTouchTime=0f;

        //public float normalizedTime=0f;
        public float currentOfTime=0f;

        //public float freezedNormalizedTime=0f;
        public float freezedCurrentOfTime=0f;
        public float totalRotateValue=0f;


        public float rotateCameraSpeed=5f;

        //被控制的动画
        public string controlAni;

        [HideInInspector]
        public Vector3 startTouchPosition;
        [HideInInspector]
        public Vector3 currTouchPosition;
        [HideInInspector]
        public Vector3 changedTouchPosition;
        [HideInInspector]
        public Vector3 endTouchPosition;
        [HideInInspector]
        public Vector3 cameraViewCenter;
        [HideInInspector]
        public Vector3 viewCenter;
        [HideInInspector]
        public Vector3 enemyViewCenter;
        [HideInInspector]
        public Vector3 friendViewCenter;

        public AnimationCurve shakeCurveX;
        public AnimationCurve shakeCurveY;
        public AnimationCurve shakeCurveZ;
        public AnimationCurve shakeLargeCurveX;
        public AnimationCurve shakeLargeCurveY;
        public AnimationCurve shakeLargeCurveZ;
        public int shakeState = 0;
        public float shakeTimer = 0;

        void Update()
        {
            if( !canHoldOnScreen ) return;
            if( UICamera.isOverUI ) return;

            InnerLogic();

            if( GetCanManualMoveCamera() )
            {
                ManualMoveCamera();
            }

        }

        public void LateUpdate()
        {
            if(shakeState == 1)
            {
                if(shakeTimer >= shakeCurveX.keys[shakeCurveX.keys.Length - 1].time)
                {
                    shakeState = 0;
                }
                transform.localPosition += new Vector3(shakeCurveX.Evaluate(shakeTimer),
                    shakeCurveY.Evaluate(shakeTimer), shakeCurveZ.Evaluate(shakeTimer));
                shakeTimer += Time.deltaTime;
                
            }
            else if(shakeState == 2)
            {
                if (shakeTimer >= shakeLargeCurveX.keys[shakeLargeCurveX.keys.Length - 1].time)
                {
                    shakeState = 0;
                }
                transform.localPosition += new Vector3(shakeLargeCurveX.Evaluate(shakeTimer),
                    shakeLargeCurveY.Evaluate(shakeTimer), shakeLargeCurveY.Evaluate(shakeTimer));
                shakeTimer += Time.deltaTime;
            }
            //else
            //{

            //}

        }

        void InnerLogic()
        {
            if( this.ani.GetClip( this.currAni ) )
            {
                this.currentOfTime  = this.ani[this.currAni].time;
            }
        }

        bool GetCanManualMoveCamera()
        {
            return cameraPosition == CameraPosition.Ready;
        }

        void ManualMoveCamera()
        {
            if( Input.GetKeyDown( KeyCode.Mouse0 ) && !onTouchScreen )
            {
                BeginTouchScreen();
            }
            else if( Input.GetKeyUp( KeyCode.Mouse0 ) && onTouchScreen )
            {
                EndTouchScreen();
            }
            else if( onTouchScreen )
            {
                OnManualCameraSpeed();
            }
            else
            {
                RevertManualCameraSpeed();
            }

            if( cameraState==CameraState.Free )
            {
                this.ani.enabled = true;
            }
        }

        void EndTouchScreen()
        {
            onTouchScreen = false;
            startTouchPosition = Vector3.zero;
            endTouchPosition = Vector3.zero;
            currTouchPosition = Vector3.zero;
            changedTouchPosition = Vector3.zero;
            endTouchTime = Time.time;
            this.cameraState = CameraState.ReleaseControl;
        }


        void BeginTouchScreen()
        {
            onTouchScreen=true;
            startTouchPosition = Input.mousePosition;
            currTouchPosition = Input.mousePosition;
            changedTouchPosition = Vector3.zero;
            startTouchTime = Time.time;
        }


        void OnManualCameraSpeed()
        {
            this.cameraState = CameraState.Control;
            this.controlAni = this.currAni;

            changedTouchPosition = Input.mousePosition - currTouchPosition;
            currTouchPosition = Input.mousePosition;

            if( changedTouchPosition.y!=0 || changedTouchPosition.z!=0 )
            {
                changedTouchPosition.y=0f;
                changedTouchPosition.z=0f;
            }

            float changeValue = changedTouchPosition.x;

            if( freezedCurrentOfTime==0f )
            {
                this.freezedCurrentOfTime = this.ani[this.currAni].time;
                this.ani.Stop( this.currAni );

            }

            this.ani.enabled=false;
            transform.RotateAround( cameraViewCenter, Vector3.up, changeValue*Time.deltaTime * rotateCameraSpeed );
            this.totalRotateValue += changeValue*Time.deltaTime * rotateCameraSpeed;

        }

        void RevertManualCameraSpeed()
        {
            if( cameraState== CameraState.Control )
            {
                cameraState = CameraState.ReleaseControl;
            }
            if( cameraState == CameraState.ReleaseControl )
            {
                if( this.totalRotateValue > 1f || this.totalRotateValue < -1f )
                {
                    float rotateValue = Mathf.Lerp( this.totalRotateValue, 0, Time.deltaTime*5 );
                    transform.RotateAround( cameraViewCenter, Vector3.up, (rotateValue-totalRotateValue) );
                    this.totalRotateValue = rotateValue;
                }

                else
                {
                    transform.RotateAround( cameraViewCenter, Vector3.up, this.totalRotateValue );
                    this.totalRotateValue = 0f;
                    this.cameraState = CameraState.Free;
                }
            }
            if( this.cameraState == CameraState.Free && freezedCurrentOfTime != 0f )
            {
                this.ani.enabled=true;
                this.ani[this.currAni].time = freezedCurrentOfTime;
                this.ani.Play( this.currAni );
                this.ani[this.currAni].speed=isRevert?-1:1;
                this.freezedCurrentOfTime=0f;
            }
        }
        #endregion
    }
}